package tech.aistar.controller;


import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
import tech.aistar.common.App;
import tech.aistar.common.Message;
import tech.aistar.common.WebJavaComilper;
import tech.aistar.common.WebJavaRunner;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@WebServlet("/api")
public class ApiServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private WebJavaComilper comilper = new WebJavaComilper();
	private WebJavaRunner runner = new WebJavaRunner();

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		Message message = new Message();
		PrintWriter out = response.getWriter();
		long flag = System.currentTimeMillis();
		Map<String, String[]> map = request.getParameterMap();
		int timeout  = Integer.valueOf(map.get("timeout")[0]) * 1000;
		String base = request.getServletContext().getRealPath("/native");
		File baseFile = new File(base);
		baseFile.mkdir();
		Pattern pattern = Pattern.compile(App.CLASS_REGEXP);
		Matcher matcher = pattern.matcher(map.get("code")[0]);
		String className = matcher.find() ? matcher.group(2) : "Main";
		File javaFile = new File(base, className + ".java");
		File inFile = new File(base, "in.txt");
		javaFile.createNewFile();
		inFile.createNewFile();
		FileUtils.write(javaFile, map.get("code")[0], "utf-8");
		comilper.setJavaName(className);
		comilper.setJavaPath(base);
		List<String> err = comilper.comilper();
		if(!err.isEmpty()) {
			for (int i = 0; i < err.size(); i++) {
				err.set(i, "<p> < "+err.get(i)+"<p>");
			}
			message.setCode(Message.FAILURE);
			message.setData(err);
			message.setMsg("FAILURE");
			long cureent  = System.currentTimeMillis();
			String time = String.format("%.2f", (cureent-flag)*1.0/1000);
			if(time.endsWith("0")) {
				time = time.substring(0,time.length()-1);
			}
			message.setTime(time);
			out.println(JSON.toJSONString(message));
		}else {
			if(!map.get("param")[0] .trim().isEmpty()) {
				FileUtils.write(inFile, map.get("param")[0], "utf-8");
				runner.setIn(inFile.getAbsolutePath());
				runner.setInput(true);
			}
			runner.setClassPath(base);
			runner.setName(className);
			runner.setTimeout(timeout);
			List<String> result = runner.executor();
			File[] files = baseFile.listFiles();
			for (File file : files) {
				file.delete();
			}
			baseFile.delete();
			List<String> data = new ArrayList<String>();
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < result.size(); i++) {
				String e = result.get(i);
				Pattern pattern1 = Pattern.compile(App.EXCEPTION_REGEXP);
				Matcher matcher1 = pattern1.matcher(e);
				if(matcher1.find()) {
					sb.append(matcher1.group(1));
				}
				Pattern pattern2 = Pattern.compile(App.EXCEPTION_LINE_REGEXP.replace("@", className));
				Matcher matcher2 = pattern2.matcher(e);
				if(matcher2.find()) {
					sb.append(" ："+matcher2.group(1));
				}
			}
			boolean main = true;
			if(result != null && result.size() == 1 && result.get(0).equals(App.NOTMAIN)) {
				main = false;
				message.setCode(Message.FAILURE);
				message.setMsg("FAILURE");
				data.add("<p> > no found main method<p>");
			}
			if(main) {
				if(sb.length() == 0) {
					for (int i = 0; i < result.size(); i++) {
						data.add("<p> > " + result.get(i) + "<p>");
					}
				}else {
					message.setCode(Message.FAILURE);
					message.setMsg("FAILURE");
					data.add("<p> > " + sb.toString() + "</p>");
				}
			}
			message.setData(data);
			long cureent  = System.currentTimeMillis();
			String time = String.format("%.2f", (cureent-flag)*1.0/1000);
			if(time.endsWith("0")) {
				time = time.substring(0,time.length()-1);
			}
			message.setTime(time);
			out.print(JSON.toJSONString(message));
		}
	}
}
